package com.zmc.lostfound.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmc.lostfound.common.exception.MyException;
import com.zmc.lostfound.common.utils.PageParams;
import com.zmc.lostfound.common.utils.PageResult;
import com.zmc.lostfound.common.utils.Result;
import com.zmc.lostfound.common.utils.redis.RedisCacheUtil;
import com.zmc.lostfound.system.dao.FeedbackDao;
import com.zmc.lostfound.system.dao.FunctionDao;
import com.zmc.lostfound.system.entity.FeedbackEntity;
import com.zmc.lostfound.system.entity.FunctionEntity;
import com.zmc.lostfound.system.service.FunctionService;
import com.zmc.lostfound.system.vo.FunctionSaveVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.zmc.lostfound.common.constant.RedisConstant.CACHE_FUNCTION_LIST_KEY;
import static com.zmc.lostfound.common.constant.RedisConstant.CACHE_FUNCTION_LIST_KEY_TTL;

/**
 * @author LJQ
 * @description 系统功能信息管理业务接口
 */
@Service
public class FunctionServiceImpl extends ServiceImpl<FunctionDao, FunctionEntity> implements FunctionService {

    private final FeedbackDao feedbackDao;

    private final RedisCacheUtil redisCacheUtil;

    public FunctionServiceImpl(FeedbackDao feedbackDao, RedisCacheUtil redisCacheUtil) {
        this.feedbackDao = feedbackDao;
        this.redisCacheUtil = redisCacheUtil;
    }

    /**
     * 分页模糊查询系统功能信息
     *
     * @param pageParams 分页参数
     * @return PageResult
     */
    @Override
    public PageResult queryPage(PageParams pageParams) {
        Integer pageNo = pageParams.getPageNo();
        Integer pageSize = pageParams.getPageSize();
        String keyword = pageParams.getKeyword();
        PageResult pageResult = new PageResult(pageNo, pageSize);
        // 1.查询所有系统功能
        List<FunctionEntity> functionList = this.findAll();
        // 2.大小写不敏感的模糊查询
        if (StrUtil.isNotBlank(keyword)) {
            Pattern pattern = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
            functionList = functionList.stream()
                    .filter(functionEntity -> {
                        Matcher matcherName = pattern.matcher((functionEntity.getFunctionName()));
                        Matcher matcherCode = pattern.matcher((functionEntity.getFunctionCode()));
                        return (matcherName.find() || matcherCode.find() || keyword.equals(functionEntity.getId().toString()));
                    }).collect(Collectors.toList());
        }
        if (CollectionUtil.isEmpty(functionList)) {
            pageResult.setTotalCount(0);
            pageResult.setTotalPage(0);
            return pageResult;
        }
        pageResult.setTotalCount(functionList.size());
        pageResult.calculateTotalPage();
        // 3.分页
        functionList = functionList.stream()
                .skip((pageNo - 1) * pageSize)
                .limit(pageSize)
                .collect(Collectors.toList());
        pageResult.setDataList(functionList);
        return pageResult;
    }

    /**
     * 查询全部系统功能信息
     *
     * @return List<FunctionEntity>
     */
    @Override
    public List<FunctionEntity> findAll() {
        return redisCacheUtil.queryList(CACHE_FUNCTION_LIST_KEY, FunctionEntity.class, "asc", this::getAll,
                CACHE_FUNCTION_LIST_KEY_TTL, TimeUnit.SECONDS);
    }

    /**
     * 查询全部物品类型
     *
     * @return List<FunctionEntity>
     */
    private List<FunctionEntity> getAll(String sort) {
        return this.query()
                .orderBy(sort != null, "asc".equals(sort), "id")
                .list();
    }

    /**
     * 按id查询系统功能信息
     *
     * @param id 系统功能id
     * @return FunctionEntity
     */
    @Override
    public FunctionEntity queryInfoById(Long id) {
        if (id == null || id <= 0) {
            MyException.throwException("查询失败: 系统功能id不能为null且必须大于0");
        }
        return this.getById(id);
    }

    /**
     * 新增系统功能信息
     *
     * @param functionSaveVO 系统功能信息新增/修改请求体
     * @return Result
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result insertFunction(FunctionSaveVO functionSaveVO) {
        FunctionEntity functionEntity = BeanUtil.copyProperties(functionSaveVO, FunctionEntity.class);
        if (!this.save(functionEntity)) {
            MyException.throwException("新增系统功能信息失败");
        }
        // 删除redis缓存
        redisCacheUtil.deleteByKey(CACHE_FUNCTION_LIST_KEY);
        return Result.ok("新增成功");
    }

    /**
     * 修改系统功能信息
     *
     * @param functionSaveVO 系统功能信息新增/修改请求体
     * @return Result
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result updateFunction(FunctionSaveVO functionSaveVO) {
        FunctionEntity functionEntity = BeanUtil.copyProperties(functionSaveVO, FunctionEntity.class);
        if (!this.updateById(functionEntity)) {
            MyException.throwException("修改系统功能信息失败");
        }
        // 删除redis缓存
        redisCacheUtil.deleteByKey(CACHE_FUNCTION_LIST_KEY);
        return Result.ok("修改成功");
    }

    /**
     * 按系统功能id删除系统功能信息
     *
     * @param functionId 系统功能id
     * @return Result
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result deleteByFunctionId(Long functionId) {
        if (functionId == null || functionId <= 0) {
            MyException.throwException("删除失败: 系统功能id不能为null且必须大于0");
        }
        // 按系统功能id删除用户反馈信息
        feedbackDao.delete(new QueryWrapper<FeedbackEntity>().eq("function_id", functionId));
        // 删除该系统功能信息
        this.removeById(functionId);
        // 删除redis缓存
        redisCacheUtil.deleteByKey(CACHE_FUNCTION_LIST_KEY);
        return Result.ok("删除成功");
    }

}